<?php
// Rekognition API
require_once 'library/rekognition/config.php';
require_once 'library/rekognition/Rekognition_API.php';
require_once 'library/rekognition/Rekognition_GUI.php';

require ('facebook/php-sdk-v4/autoload.php');
require 'cloudiary/Cloudinary.php';
require 'cloudiary/Uploader.php';
require 'cloudiary/Api.php';
global $rekognition;

// Facedetector
use svay\FaceDetector;
require_once 'library/ThumbLib.inc.php';
require_once 'library/FaceDetector/FaceDetector.php';
class Mimage extends CI_Model {
	private $rekognition;
	public function __construct() {
		parent::__construct ();
		$this->load->helper ( 'url' );
		$this->load->library ( 'session' );
		$this->load->library ( 'image_lib' );
		\Cloudinary::config(array(
				"cloud_name" => $this->config->item('cloud_name'),
				"api_key" => $this->config->item('api_key'),
				"api_secret" => $this->config->item('api_secret')
		));
	}
	
	// relative path
	public function getSize($imagePath) {
		$size = getimagesize ( $imagePath );
		return $size;
	}
	public function resizePercent($percent) {
		$userId = $_SESSION ["userId"];
		$imageName = $_SESSION ["imageName"];
		$fileName = "./UserUploads/" . $userId . "/" . $imageName;
		$thumb = PhpThumbFactory::create ( $fileName );
		// resize image to predefined size
		$thumb->resizePercent ( $percent );
		$thumb->save ( "./UserUploads/" . $userId . "/resize" . $imageName );
	}
	public function resize($width, $heigth, $type = null) {
		$userId = $_SESSION ["userId"];
		$imageName = "";
		$fileName = "";
		if (! $type) {
			$imageName = (! isset ( $_SESSION ["isWatermarked"] )) ? $_SESSION ["imageName"] : "watermark-" . $_SESSION ["isWatermarked"];
			$fileName = (! isset ( $_SESSION ["isWatermarked"] )) ? "./UserUploads/" . $userId . "/" . $imageName : "./UserUploads/" . $userId . "/" . $imageName;
		} else if (strcmp ( $type, "twoImages" ) == 0) {
			$imageName = (! isset ( $_SESSION ["isTwoImages"] )) ? $_SESSION ["imageName"] : "twoImages-" . $_SESSION ["isTwoImages"];
			$fileName = (! isset ( $_SESSION ["isTwoImages"] )) ? "./UserUploads/" . $userId . "/" . $imageName : "./UserUploads/" . $userId . "/" . $imageName;
		}
		$thumb = PhpThumbFactory::create ( $fileName );
		// resize image to predefined size
		$thumb->resize ( $width, $heigth );
		$thumb->save ( "./UserUploads/" . $userId . "/resize" . $imageName );
	}
	public function watermark($arrayArgument) {
		$userId = $_SESSION ["userId"];
		$imageName = $_SESSION ["imageName"];
		
		// var_dump ( $arrayArgument );
		$watermarkString = $arrayArgument ["watermarkImage"];
		
		$color = $arrayArgument ["color"];
		$angle = $arrayArgument ["angle"];
		if(isset($_SESSION["imagePath"]))
			$imageSize = $this->mimage->getSize($_SESSION["imagePath"]);
		else
			$imageSize = $this->mimage->getSize("./UserUploads/$userId/default.jpg");
		$newInputWidth = 0;
		$positionX = 0;
		$positionY = 0;
		if ($angle >= 270 && $angle < 359) {
			$positionX = $arrayArgument ["coordinateX"];
			$positionY = $arrayArgument ["coordinateY"];
		} else if ($angle >= 180 && $angle < 270) {
			$positionX = $arrayArgument ["coordinateX"] + 140 * cos ( ($angle - 180) * pi () / 180 );
			$positionY = $arrayArgument ["coordinateY"];
		} else if ($angle >= 90 && $angle < 180) {
			$positionX = $arrayArgument ["coordinateX"] + 140 * sin ( (180 - $angle) * pi () / 180 );
			$positionY = $arrayArgument ["coordinateY"] + 140 * cos ( (180 - $angle) * pi () / 180 );
		} else if ($angle >= 0 && $angle < 90) {
			$positionX = $arrayArgument ["coordinateX"];
			$positionY = $arrayArgument ["coordinateY"] + 140 * sin ( (180 - $angle) * pi () / 180 );
		}
		
		$red = hexdec ( substr ( $color, 0, 2 ) );
		$green = hexdec ( substr ( $color, 2, 2 ) );
		$blue = hexdec ( substr ( $color, 4, 2 ) );
		if(!isset($_SESSION["imagePath"]))
			$originalPath = "./UserUploads/" . $userId . "/" . $imageName;
		else
			$originalPath = $_SESSION["imagePath"];
		$resultPath = "./UserUploads/" . $userId . "/watermark-" . $imageName;
		$size = getimagesize ( $originalPath );
		
		list ( $width, $height ) = getimagesize ( $originalPath );
		$image_p = imagecreatetruecolor ( $width, $height );
		$image = imagecreatefromjpeg ( $originalPath );
		imagecopyresampled ( $image_p, $image, 0, 0, 0, 0, $width, $height, $width, $height );
		$black = imagecolorallocate ( $image_p, $red, $green, $blue );
		$font = "./style/font/1980PORT.ttf";
		$font_size = 30;
		
		// watermark size
		
		// create the new image
		// array imagettftext ( resource $image , float $size , float $angle , int $x , int $y , int $color , string $fontfile , string $text )
		imagettftext ( $image_p, $font_size, $angle, $positionX, $positionY, $black, $font, $watermarkString );
		
		imagejpeg ( $image_p, $resultPath, 100 );
		
		$_SESSION ["isWatermarked"] = $imageName;
		$outputName = "watermark-".$imageName;
		$outputNameOnly = preg_replace("/\.\w+/", "", $outputName);
		
		$cloudUpload = \Cloudinary\Uploader::upload($resultPath, array("public_id" => "UserUploads/$userId/$outputNameOnly"));
		//delete in server
		$_SESSION["watermarkPath"] = $cloudUpload["url"];
		unlink($resultPath);
		imagedestroy ( $image );
		imagedestroy ( $image_p );
	}
	// Da thu chuyen sang PNG nhung vo dung
	public function twoImages($arrayArgument) {
		$userId = $_SESSION ["userId"];
		$imageName = $_SESSION ["imageName"];
		var_dump ( $arrayArgument );
		echo "</br>";
		
		if(!isset($_SESSION["imagePath"]))
			$userImage = base_url () . "UserUploads/" . $userId . "/" . $imageName;
		else 
			$userImage = $_SESSION["imagePath"];
		
		$backgroundImgPath = (strcmp ( $arrayArgument ["backgroundName"], "" ) != 0 && strcmp ( $arrayArgument ["backgroundName"], "defaultBackground.jpeg" ) != 0) ? $_SESSION["backgroundPath"] : base_url () ."UserUploads/defaultBackground.jpeg";
		
		echo $userImage . "</br>";
		echo $backgroundImgPath . "</br>";
		// must use relative path
		$result = "./UserUploads/" . $userId . "/twoImages-" . $imageName;
		// source image
		// $config ['source_image'] = $userImage;
		$rate = $arrayArgument ["line-style"];
		$backgroundRate = ($rate >= 1 && $rate <= 7) ? 100 : (($rate == 8 || $rate == 9) ? 20 : (($rate == 10 || $rate == 11) ? 30 : (($rate == 12 || $rate == 13) ? 40 : (($rate == 14 || $rate == 15) ? 50 : (($rate == 16 || $rate == 17) ? 60 : 80)))));
		$backgroundRate /= 100;
		
		$imageRate = ($rate == 1 || $rate == 8 || $rate == 10 || $rate == 12 || $rate == 14 || $rate == 16 || $rate == 18) ? 100 : (($rate == 2 || $rate == 19) ? 20 : (($rate == 3 || $rate == 17) ? 40 : (($rate == 4 || $rate == 15) ? 50 : (($rate == 13 || $rate == 5) ? 60 : (($rate == 6 || $rate == 11) ? 70 : 80)))));
		$imageRate /= 100;
		// echo $backgroundRate."---".$imageRate."</br>";
		
		try {
			$imageSize = getimagesize($userImage);
			$tmpWidth = 188;
			$tmpHeight = $imageSize[1]*188/$imageSize[0];
			$tmp = "188x$tmpHeight";
			
			$command = "convert " . $userImage . " -resize $tmp! " . "./$destination/tmpUserImage.jpg";
			exec ( $command );
			$resultUserImg = new Imagick ( "./$destination/tmpUserImage.jpg" );

			$resultUserImg->setformat("png");
			$resultUserImg->evaluateImage ( Imagick::EVALUATE_MULTIPLY, $imageRate, Imagick::CHANNEL_ALPHA );
			
			$resultBackgroundImg = new Imagick ( $backgroundImgPath );
			$resultBackgroundImg->setformat("png");
			$resultBackgroundImg->setimageopacity ( $backgroundRate );
			
			$dst_x = $arrayArgument ["imagePositionX"];
			$dst_y = $arrayArgument ["imagePositionY"];
			
			$resultBackgroundImg->compositeimage ( $resultUserImg, Imagick::COMPOSITE_OVER, $dst_x, $dst_y );
			
			$resultBackgroundImg->writeimage ( "$result" );
			$_SESSION ["isTwoImages"] = $imageName;
			$outputName = "twoImages-".$imageName;
			$outputNameOnly = preg_replace("/\.\w+/", "", $outputName);
			
			$cloudUpload = \Cloudinary\Uploader::upload("./UserUploads/$userId/$outputName", array("public_id" => "UserUploads/$userId/$outputNameOnly"));
			//delete in server
			$_SESSION["twoImagesPath"] = $cloudUpload["url"];
			unlink("./UserUploads/$userId/$outputName");
			unlink("./UserUploads/$userId/tmpUserImage.jpg");
		} catch ( Exception $e ) {
			echo $e->getMessage ();
		}
	}
	public function imageFrame($frameImgPath, $frameNumber) {
		session_start ();
		$userId = $_SESSION ["userId"];
		$imageName = $_SESSION ["imageName"];
		$frameImg = new Imagick ( base_url () . $frameImgPath );
		
		if(!isset($_SESSION["imagePath"]))
			$userImage = base_url () . "UserUploads/" . $userId . "/" . $imageName;
		else
			$userImage = $_SESSION["imagePath"];
		// must use relative path
		$result = "./UserUploads/" . $userId . "/frame-" . $imageName;
		switch ($frameNumber) {
			case 1 :
				try {
					$image = new Imagick ( $userImage );
					$image->adaptiveResizeImage ( 433, 600 );
					$dst_x = 0;
					$dst_y = 0;
					$image->compositeimage ( $frameImg, Imagick::COMPOSITE_OVER, $dst_x, $dst_y );
					$image->writeimage ( $result );
				} catch ( Exception $e ) {
					echo ($e->getMessage ());
				}
				break;
			
			case 2 :
				try {
					$image = new Imagick ( $userImage );
					$image->adaptiveResizeImage ( 433, 600 );
					$dst_x = 0;
					$dst_y = 0;
					$image->compositeimage ( $frameImg, Imagick::COMPOSITE_OVER, $dst_x, $dst_y );
					$image->writeimage ( $result );
				} catch ( Exception $e ) {
					echo ($e->getMessage ());
				}
				break;
			
			case 3 :
				try {
					$deltaTop = 80;
					$deltaBot = 120;
					$deltaLeft = 156;
					$deltaRight = 143;
					$image = new Imagick ( $userImage );
					$image->adaptiveResizeImage ( 313, 260 );
					
					$size = getimagesize ( "." . $frameImgPath );
					$image->extentimage ( $size [0], $size [1], - $deltaLeft, - $deltaTop );
					$image->setbackgroundcolor ( new ImagickPixel ( 'transparent' ) );
					
					// header("Content-type: image/png");
					// echo $image;
					$dst_x = 0;
					$dst_y = 0;
					$image->compositeimage ( $frameImg, Imagick::COMPOSITE_OVER, $dst_x, $dst_y );
					$image->writeimage ( $result );
				} catch ( Exception $e ) {
					echo ($e->getMessage ());
				}
				break;
			case 4 :
				try {
					$deltaTop = 76;
					$deltaLeft = 54;
					$image = new Imagick ( $userImage );
					$image->adaptiveResizeImage ( 340, 430 );
					
					$size = getimagesize ( "." . $frameImgPath );
					$image->extentimage ( $size [0], $size [1], - $deltaLeft, - $deltaTop );
					$image->setbackgroundcolor ( new ImagickPixel ( 'transparent' ) );
					
					// header("Content-type: image/png");
					// echo $image;
					$dst_x = 0;
					$dst_y = 0;
					$image->compositeimage ( $frameImg, Imagick::COMPOSITE_OVER, $dst_x, $dst_y );
					$image->writeimage ( $result );
				} catch ( Exception $e ) {
					echo ($e->getMessage ());
				}
				break;
			case 5 :
				try {
					$deltaTop = 75;
					$deltaLeft = 40;
					$image = new Imagick ( $userImage );
					$image->adaptiveResizeImage ( 290, 371 );
					
					$size = getimagesize ( "." . $frameImgPath );
					// sau khi rotate image van giu
					$image->rotateimage ( "none", 9 );
					$image->extentimage ( $size [0], $size [1], - $deltaLeft, - $deltaTop );
					$image->setbackgroundcolor ( new ImagickPixel ( 'transparent' ) );
					$dst_x = 0;
					$dst_y = 0;
					$image->compositeimage ( $frameImg, Imagick::COMPOSITE_OVER, $dst_x, $dst_y );
					$image->writeimage ( $result );
				} catch ( Exception $e ) {
					echo ($e->getMessage ());
				}
				break;
			
			case 6 :
				try {
					$deltaTop = 52;
					$deltaLeft = 280;
					$image = new Imagick ( $userImage );
					$image->adaptiveResizeImage ( 305, 326 );
					
					$size = getimagesize ( "." . $frameImgPath );
					$image->extentimage ( $size [0], $size [1], - $deltaLeft, - $deltaTop );
					$image->setbackgroundcolor ( new ImagickPixel ( 'transparent' ) );
					$dst_x = 0;
					$dst_y = 0;
					$image->compositeimage ( $frameImg, Imagick::COMPOSITE_OVER, $dst_x, $dst_y );
					$image->writeimage ( $result );
				} catch ( Exception $e ) {
					echo ($e->getMessage ());
				}
				break;
			
			case 7 :
				try {
					$deltaTop = 40;
					$deltaLeft = 30;
					$image = new Imagick ( $userImage );
					$image->adaptiveResizeImage ( 340, 525 );
					
					$size = getimagesize ( "." . $frameImgPath );
					$image->extentimage ( $size [0], $size [1], - $deltaLeft, - $deltaTop );
					$image->setbackgroundcolor ( new ImagickPixel ( 'transparent' ) );
					$dst_x = 0;
					$dst_y = 0;
					$image->compositeimage ( $frameImg, Imagick::COMPOSITE_OVER, $dst_x, $dst_y );
					$image->writeimage ( $result );
				} catch ( Exception $e ) {
					echo ($e->getMessage ());
				}
				break;
			
			case 8 :
				try {
					$deltaTop = 0;
					$deltaLeft = 0;
					$image = new Imagick ( $userImage );
					$image->adaptiveResizeImage ( 375, 385 );
					
					$size = getimagesize ( "." . $frameImgPath );
					$image->extentimage ( $size [0], $size [1], - $deltaLeft, - $deltaTop );
					$image->setbackgroundcolor ( new ImagickPixel ( 'transparent' ) );
					$dst_x = 0;
					$dst_y = 0;
					$image->compositeimage ( $frameImg, Imagick::COMPOSITE_OVER, $dst_x, $dst_y );
					$image->writeimage ( $result );
				} catch ( Exception $e ) {
					echo ($e->getMessage ());
				}
				break;
			
			case 9 :
				try {
					$deltaTop = 0;
					$deltaLeft = 0;
					$image = new Imagick ( $userImage );
					$image->adaptiveResizeImage ( 417, 516 );
					
					$size = getimagesize ( "." . $frameImgPath );
					$image->extentimage ( $size [0], $size [1], - $deltaLeft, - $deltaTop );
					$image->setbackgroundcolor ( new ImagickPixel ( 'transparent' ) );
					$dst_x = 0;
					$dst_y = 0;
					$image->compositeimage ( $frameImg, Imagick::COMPOSITE_OVER, $dst_x, $dst_y );
					$image->writeimage ( $result );
				} catch ( Exception $e ) {
					echo ($e->getMessage ());
				}
				break;
			
			case 10 :
				try {
					$deltaTop = 175;
					$deltaLeft = 45;
					$image = new Imagick ( $userImage );
					$image->rotateimage ( new ImagickPixel ( "#632810" ), 0 );
					$image->adaptiveResizeImage ( 300, 190 );
					
					$size = getimagesize ( "." . $frameImgPath );
					$image->extentimage ( $size [0], $size [1], - $deltaLeft, - $deltaTop );
					$image->setbackgroundcolor ( 'transparent' );
					
					$dst_x = 0;
					$dst_y = 0;
					$image->compositeimage ( $frameImg, Imagick::COMPOSITE_OVER, $dst_x, $dst_y );
					$image->writeimage ( $result );
				} catch ( Exception $e ) {
					echo ($e->getMessage ());
				}
				break;
			
			case 11 :
				try {
					$deltaTop = 40;
					$deltaLeft = 70;
					$image = new Imagick ( $userImage );
					$image->rotateimage ( new ImagickPixel ( "#88DCCE" ), 15 );
					$image->adaptiveResizeImage ( 495, 350 );
					
					$size = getimagesize ( "." . $frameImgPath );
					// sau khi rotate image van giu
					
					$image->extentimage ( $size [0], $size [1], - $deltaLeft, - $deltaTop );
					$image->setbackgroundcolor ( new ImagickPixel ( 'transparent' ) );
					$dst_x = 0;
					$dst_y = 0;
					$image->compositeimage ( $frameImg, Imagick::COMPOSITE_OVER, $dst_x, $dst_y );
					$image->writeimage ( $result );
				} catch ( Exception $e ) {
					echo ($e->getMessage ());
				}
				break;
			
			case 12 :
				try {
					$deltaTop = 7;
					$deltaLeft = 40;
					$image = new Imagick ( $userImage );
					$image->rotateimage ( "none", - 15 );
					$image->adaptiveResizeImage ( 255, 390 );
					
					$size = getimagesize ( "." . $frameImgPath );
					// sau khi rotate image van giu
					
					$image->extentimage ( $size [0], $size [1], - $deltaLeft, - $deltaTop );
					$image->setbackgroundcolor ( new ImagickPixel ( 'transparent' ) );
					$dst_x = 0;
					$dst_y = 0;
					$image->compositeimage ( $frameImg, Imagick::COMPOSITE_OVER, $dst_x, $dst_y );
					
					$deltaTop2 = 20;
					$deltaLeft2 = 315;
					$image2 = new Imagick ( $userImage );
					$image2->rotateimage ( new ImagickPixel ( "#88DCCE" ), - 15 );
					$image2->adaptiveResizeImage ( 255, 390 );
					
					// sau khi rotate image van giu
					
					$image2->extentimage ( $size [0], $size [1], - $deltaLeft2, - $deltaTop2 );
					$image2->setbackgroundcolor ( new ImagickPixel ( 'transparent' ) );
					$dst_x = 0;
					$dst_y = 0;
					$image2->compositeimage ( $image, Imagick::COMPOSITE_OVER, $dst_x, $dst_y );
					
					$image2->writeimage ( $result );
				} catch ( Exception $e ) {
					echo ($e->getMessage ());
				}
				break;
			case 13 :
				try {
					$deltaTop = 89;
					$deltaLeft = 82;
					$image = new Imagick ( $userImage );
					$image->adaptiveResizeImage ( 270, 357 );
					
					$size = getimagesize ( "." . $frameImgPath );
					// sau khi rotate image van giu
					
					$image->extentimage ( $size [0], $size [1], - $deltaLeft, - $deltaTop );
					$image->setbackgroundcolor ( new ImagickPixel ( 'transparent' ) );
					$dst_x = 0;
					$dst_y = 0;
					$image->compositeimage ( $frameImg, Imagick::COMPOSITE_OVER, $dst_x, $dst_y );
					$image->writeimage ( $result );
				} catch ( Exception $e ) {
					echo ($e->getMessage ());
				}
				break;
			case 14 :
				try {
					$deltaTop = 31;
					$deltaLeft = 225;
					$image = new Imagick ( $userImage );
					$image->rotateimage ( "none", - 12 );
					$image->adaptiveResizeImage ( 344, 330 );
					
					$size = getimagesize ( "." . $frameImgPath );
					// sau khi rotate image van giu
					
					$image->extentimage ( $size [0], $size [1], - $deltaLeft, - $deltaTop );
					$image->setbackgroundcolor ( new ImagickPixel ( 'transparent' ) );
					$dst_x = 0;
					$dst_y = 0;
					$image->compositeimage ( $frameImg, Imagick::COMPOSITE_OVER, $dst_x, $dst_y );
					$image->writeimage ( $result );
				} catch ( Exception $e ) {
					echo ($e->getMessage ());
				}
				break;
			default :
				;
				break;
		}
		$_SESSION ["isFramed"] = $imageName;
		$outputName = "frame-".$imageName;
		$outputNameOnly = preg_replace("/\.\w+/", "", $outputName);
		
		$cloudUpload = \Cloudinary\Uploader::upload("./UserUploads/$userId/$outputName", array("public_id" => "UserUploads/$userId/$outputNameOnly"));
		//delete in server
		$_SESSION["framePath"] = $cloudUpload["url"];
		unlink("./UserUploads/$userId/$outputName");
	}
	public function makeCartoon() {
		$userId = $_SESSION ["userId"];
		$imageName = $_SESSION ["imageName"];
		
		if(!isset($_SESSION["imagePath"]))
			$userImagePath = base_url () . "UserUploads/" . $userId . "/" . $imageName;
		else 
			$userImagePath = $_SESSION["imagePath"];
		$userImage = new Imagick ( $userImagePath );
		// -p ... pattern ...... segmentation pattern (shape); 0<=integer<=100;
		// ..................... default=70
		// -n ... numlevels .... number of desired segmentation levels; integer>=2;
		// ..................... default=6
		// -e ... edgeamount ... amount of edges; float>=0; default=4
		// -b ... brightness ... brightness of cartoon; integer>=0; default=100
		// -s ... saturation ... saturation of cartoon; integer>=0; default=150
		
		$outputName = "cartoon-" . $imageName;
		exec ( "./bashscript/cartoon -p 80 -n 6 -e 3 -b 80 -s 150 $userImagePath  ./UserUploads/$userId/$outputName" );
		exec ( "./bashscript/statsfilt -s 13 ./UserUploads/$userId/$outputName  ./UserUploads/$userId/$outputName" );
		exec ( "./bashscript/ortoneffect -b 5 -o 100 ./UserUploads/$userId/$outputName  ./UserUploads/$userId/$outputName" );
		// -k ... kind ... kind of grayscale conversion; options are gray(g) or
		// ............... desat(d); default=desat
		// -e ... edge ... edge coarseness; integer>0; default=4
		// -c ... con .... percent contrast change; integer>=0; default=125
		// -s ... sat .... percent saturation change; integer>=0; default=100
		// -g ............ output grayscale only
		// exec("./bashscript/sketch -k desat -c 125 -g ./UserUploads/$userId/$imageName ./UserUploads/$userId/$imageName", $output, $return);
		// exec("./bashscript/sketch -k desat -e 4 -c 125 ./UserUploads/$userId/$imageName ./UserUploads/$userId/$imageName", $output, $return);
		
		// exec("./bashscript/sketch -k desat -e 4 -c 125 ./UserUploads/$userId/$imageName ./UserUploads/$userId/$imageName", $output, $return);
		$outputNameOnly = preg_replace("/\.\w+/", "", $outputName);
		
		$cloudUpload = \Cloudinary\Uploader::upload("./UserUploads/$userId/$outputName", array("public_id" => "UserUploads/$userId/$outputNameOnly"));
		//delete in server
		$_SESSION["cartoonPath"] = $cloudUpload["url"];
		unlink("./UserUploads/$userId/$outputName");
	}
	public function makeFunnyEffect($beardPath, $hairPath, $nosePath) {
		session_start ();
		$userId = $_SESSION ["userId"];
		$imageName = $_SESSION ["imageName"];
		
		if(!isset($_SESSION["imagePath"]))
			$userImagePath = base_url () . "UserUploads/" . $userId . "/" . $imageName;
		else 
			$userImagePath = $_SESSION["imagePath"];
		// echo "Before analyzing:<br><br><img src=$userImagePath></img><br><br>";
		
		$dir = $userImagePath;
		
		global $rekognition;
		$resize_factor = 1;
		$parsed_obj = $rekognition->RkFaceDetect ( $dir, $resize_factor, Rekognition_API::REQUEST_DIR, Rekognition_API::RETURN_PARSED );
		
		global $orbgui;
		$orbgui->SetImage ( $dir );
		$orbgui->DrawObjects ( $parsed_obj->GetFaces (), $resize_factor );
		
		$base64_str = base64_encode ( $orbgui->GetImage () );
		// echo "After analyzing:<br><br><img src='data:image/jpeg;base64," . $base64_str . "' /><br><br>";
		
		$resultArray = ( array ) $parsed_obj;
		
		$returnFaceAttr;
		// counter for Rekognition_Parserfaces_
		$i = 0;
		foreach ( $resultArray as $key => $value ) {
			$tmp = $key;
			if ($i == 2) {
				$returnFaceAttr = ( array ) $resultArray [$key] [0];
				break;
			}
			// strlen vs mb_strlen;
			// http://wpengineer.com/2410/dont-use-strlen/
			$i ++;
		}
		
		$j = 0;
		$faceBound = array ();
		$leftEye = array ();
		$rightEye = array ();
		$nose = array ();
		$leftMounth = array ();
		$rightMounth = array ();
		
		foreach ( $returnFaceAttr as $key => $value ) {
			if ($j == 1) {
				$faceBound = ( array ) $returnFaceAttr [$key];
			} else if ($j == 3) {
				$features = $returnFaceAttr [$key];
				$x = 0;
				foreach ( $features as $key__ => $value__ ) {
					if ($x == 0) {
						$leftEye = ( array ) $features [$key__];
					} else if ($x == 1) {
						$rightEye = ( array ) $features [$key__];
					} else if ($x == 2) {
						$nose = ( array ) $features [$key__];
					} else if ($x == 3) {
						$leftMounth = ( array ) $features [$key__];
					} else if ($x == 5) {
						$rightMounth = ( array ) $features [$key__];
						break;
					}
					$x ++;
				}
				break;
			}
			$j ++;
		}
		
		// Make face
		$boundLeftX = 0;
		$boundLeftY = 0;
		$boundBoxWidth = 0;
		$boundBoxHeight = 0;
		$i = 0;
		foreach ( $faceBound as $key => $value ) {
			if ($i == 0) {
				$boundLeft = ( array ) $faceBound [$key];
				$j = 0;
				foreach ( $boundLeft as $keyJ => $valueJ ) {
					if ($j == 0)
						$boundLeftX = $boundLeft [$keyJ];
					else
						$boundLeftY = $boundLeft [$keyJ];
					$j ++;
				}
			} else if ($i == 1) {
				$boundBox = ( array ) $faceBound [$key];
				$j = 0;
				foreach ( $boundBox as $keyJ => $valueJ ) {
					if ($j == 0)
						$boundBoxWidth = $boundBox [$keyJ];
					else
						$boundBoxHeight = $boundBox [$keyJ];
					$j ++;
				}
			}
			
			$i ++;
		}
		$faceCoord = array (
				$boundLeftX,
				$boundLeftY,
				$boundBoxWidth + 20,
				$boundBoxHeight + 20 
		);
		// Make Eye
		$leftEyeX = 0;
		$leftEyeY = 0;
		$rightEyeX = 0;
		$rightEyeY = 0;
		$i = 0;
		foreach ( $leftEye as $key => $value ) {
			if ($i == 0)
				$leftEyeX = $leftEye [$key];
			else
				$leftEyeY = $leftEye [$key];
			$i ++;
		}
		$i = 0;
		foreach ( $rightEye as $key => $value ) {
			if ($i == 0)
				$rightEyeX = $rightEye [$key];
			else
				$rightEyeY = $rightEye [$key];
			$i ++;
		}
		$eyeCoord = array (
				$leftEyeX,
				$leftEyeY,
				$rightEyeX,
				$rightEyeY 
		);
		
		// Make Nose
		$noseX = 0;
		$noseY = 0;
		$i = 0;
		foreach ( $nose as $key => $value ) {
			if ($i == 0)
				$noseX = $nose [$key];
			else
				$noseY = $nose [$key];
			$i ++;
		}
		
		$noseCoord = array (
				$noseX,
				$noseY 
		);
		// Make Mounth
		$leftMounthX = 0;
		$leftMounthY = 0;
		$i = 0;
		foreach ( $leftMounth as $key => $value ) {
			if ($i == 0)
				$leftMounthX = $leftMounth [$key];
			else
				$leftMounthY = $leftMounth [$key];
			$i ++;
		}
		$rightMounthX = 0;
		$rightMounthY = 0;
		$i = 0;
		foreach ( $rightMounth as $key => $value ) {
			if ($i == 0)
				$rightMounthX = $rightMounth [$key];
			else
				$rightMounthY = $rightMounth [$key];
			$i ++;
		}
		$mounthCoord = array (
				$leftMounthX,
				$leftMounthY,
				$rightMounthX,
				$rightMounthY 
		);
		
		// Count angle
		$twoEyesVector = array (
				$eyeCoord [2] - $eyeCoord [0],
				$eyeCoord [3] - $eyeCoord [1] 
		);
		$xUnitVector = array (
				1,
				0 
		);
		$rotateAngle = 180 / pi () * acos ( ($twoEyesVector [0]) / sqrt ( $twoEyesVector [0] * $twoEyesVector [0] + $twoEyesVector [1] * $twoEyesVector [1] ) );
		$rotateAngle = ($eyeCoord [3] >= $eyeCoord [1]) ? - $rotateAngle : $rotateAngle;
		
		$standardEyesDistance = 85;
		$standardNoseWidth = 50;
		$standardBeardWidth = 150;
		$standardHairWidth = 235;
		
		$eyesDistances = sqrt ( ($eyeCoord [2] - $eyeCoord [0]) * ($eyeCoord [2] - $eyeCoord [0]) + ($eyeCoord [3] - $eyeCoord [1]) * ($eyeCoord [3] - $eyeCoord [1]) );
		$beardSize = (strcmp ( $beardPath, "" ) != 0) ? getimagesize ( $beardPath ) : array ();
		$noseSize = (strcmp ( $nosePath, "" ) != 0) ? getimagesize ( $nosePath ) : array ();
		$hairSize = (strcmp ( $hairPath, "" ) != 0) ? getimagesize ( $hairPath ) : array ();
		
		$proportion = $eyesDistances / $standardEyesDistance;
		// resize Beard image
		$newBeardWidth = (strcmp ( $beardPath, "" ) != 0) ? ($beardSize [0] * $proportion) . "x" : 0;
		if ((strcmp ( $beardPath, "" ) != 0))
			exec ( "convert ./$beardPath -resize $newBeardWidth ./UserUploads/$userId/beard.png" );
			// resize Nose image
		$newNoseWidth = (strcmp ( $nosePath, "" ) != 0) ? ($noseSize [0] * $proportion) . "x" : 0;
		if (strcmp ( $nosePath, "" ) != 0)
			exec ( "convert ./$nosePath -resize $newNoseWidth ./UserUploads/$userId/nose.png" );
			// resize hair image
		$newHairWidth = (strcmp ( $hairPath, "" ) != 0) ? ($hairSize [0] * $proportion) . "x" : 0;
		if (strcmp ( $hairPath, "" ) != 0)
			exec ( "convert ./$hairPath -resize $newHairWidth ./UserUploads/$userId/hair.png" );
		
		echo "</br>";
		echo $beardPath . "</br>";
		echo $nosePath . "</br>";
		echo $hairPath . "</br>";
		
		echo $newBeardWidth . "</br>";
		echo $newHairWidth . "</br>";
		echo $newNoseWidth . "</br>";
		
		echo "</br>";
		echo $rotateAngle;
		echo "</br>";
		var_dump ( $faceCoord );
		echo "</br>";
		var_dump ( $eyeCoord );
		echo "</br>";
		var_dump ( $mounthCoord );
		echo "</br>";
		var_dump ( $noseCoord );
		
		$userImage = $_SESSION["imagePath"];
		$image = new Imagick ( $userImage );
		
		// Rotate and reconignition the new one
		$image->rotateimage ( "#4BA3E6", $rotateAngle );
		$image->writeimage ( "./UserUploads/" . $userId . "/firstRotate-" . $imageName );
		// $image->rotateimage("none", -$rotateAngle);
		// $image->writeimage("./images/2__.png");
		
		// detect again
		$dir = base_url () . "UserUploads/" . $userId . "/firstRotate-" . $imageName;
		$parsed_obj = $rekognition->RkFaceDetect ( $dir, $resize_factor, Rekognition_API::REQUEST_DIR, Rekognition_API::RETURN_PARSED );
		$resultArray = ( array ) $parsed_obj;
		
		$returnFaceAttr;
		// counter for Rekognition_Parserfaces_
		$i = 0;
		foreach ( $resultArray as $key => $value ) {
			$tmp = $key;
			if ($i == 2) {
				$returnFaceAttr = ( array ) $resultArray [$key] [0];
				break;
			}
			// strlen vs mb_strlen;
			// http://wpengineer.com/2410/dont-use-strlen/
			$i ++;
		}
		
		$j = 0;
		$faceBound = array ();
		$leftEye = array ();
		$rightEye = array ();
		$nose = array ();
		$leftMounth = array ();
		$rightMounth = array ();
		
		foreach ( $returnFaceAttr as $key => $value ) {
			if ($j == 1) {
				$faceBound = ( array ) $returnFaceAttr [$key];
			} else if ($j == 3) {
				$features = $returnFaceAttr [$key];
				$x = 0;
				foreach ( $features as $key__ => $value__ ) {
					if ($x == 0) {
						$leftEye = ( array ) $features [$key__];
					} else if ($x == 1) {
						$rightEye = ( array ) $features [$key__];
					} else if ($x == 2) {
						$nose = ( array ) $features [$key__];
					} else if ($x == 3) {
						$leftMounth = ( array ) $features [$key__];
					} else if ($x == 5) {
						$rightMounth = ( array ) $features [$key__];
						break;
					}
					$x ++;
				}
				break;
			}
			$j ++;
		}
		
		// Make face
		$boundLeftX = 0;
		$boundLeftY = 0;
		$boundBoxWidth = 0;
		$boundBoxHeight = 0;
		$i = 0;
		foreach ( $faceBound as $key => $value ) {
			if ($i == 0) {
				$boundLeft = ( array ) $faceBound [$key];
				$j = 0;
				foreach ( $boundLeft as $keyJ => $valueJ ) {
					if ($j == 0)
						$boundLeftX = $boundLeft [$keyJ];
					else
						$boundLeftY = $boundLeft [$keyJ];
					$j ++;
				}
			} else if ($i == 1) {
				$boundBox = ( array ) $faceBound [$key];
				$j = 0;
				foreach ( $boundBox as $keyJ => $valueJ ) {
					if ($j == 0)
						$boundBoxWidth = $boundBox [$keyJ];
					else
						$boundBoxHeight = $boundBox [$keyJ];
					$j ++;
				}
			}
			
			$i ++;
		}
		$faceCoord = array (
				$boundLeftX,
				$boundLeftY,
				$boundBoxWidth + 20,
				$boundBoxHeight + 20 
		);
		// Make Eye
		$leftEyeX = 0;
		$leftEyeY = 0;
		$rightEyeX = 0;
		$rightEyeY = 0;
		$i = 0;
		foreach ( $leftEye as $key => $value ) {
			if ($i == 0)
				$leftEyeX = $leftEye [$key];
			else
				$leftEyeY = $leftEye [$key];
			$i ++;
		}
		$i = 0;
		foreach ( $rightEye as $key => $value ) {
			if ($i == 0)
				$rightEyeX = $rightEye [$key];
			else
				$rightEyeY = $rightEye [$key];
			$i ++;
		}
		$eyeCoord = array (
				$leftEyeX,
				$leftEyeY,
				$rightEyeX,
				$rightEyeY 
		);
		
		// Make Nose
		$noseX = 0;
		$noseY = 0;
		$i = 0;
		foreach ( $nose as $key => $value ) {
			if ($i == 0)
				$noseX = $nose [$key];
			else
				$noseY = $nose [$key];
			$i ++;
		}
		
		$noseCoord = array (
				$noseX,
				$noseY 
		);
		// Make Mounth
		$leftMounthX = 0;
		$leftMounthY = 0;
		$i = 0;
		foreach ( $leftMounth as $key => $value ) {
			if ($i == 0)
				$leftMounthX = $leftMounth [$key];
			else
				$leftMounthY = $leftMounth [$key];
			$i ++;
		}
		$rightMounthX = 0;
		$rightMounthY = 0;
		$i = 0;
		foreach ( $rightMounth as $key => $value ) {
			if ($i == 0)
				$rightMounthX = $rightMounth [$key];
			else
				$rightMounthY = $rightMounth [$key];
			$i ++;
		}
		$mounthCoord = array (
				$leftMounthX,
				$leftMounthY,
				$rightMounthX,
				$rightMounthY 
		);
		
		echo "</br>New Image After Rotate:</br>";
		var_dump ( $faceCoord );
		echo "</br>";
		var_dump ( $eyeCoord );
		echo "</br>";
		var_dump ( $mounthCoord );
		echo "</br>";
		var_dump ( $noseCoord );
		
		// Append items into new Rotated image:
		// Append beard
		if (strcmp ( $beardPath, "" ) != 0) {
			$newBeardSize = getimagesize ( "./UserUploads/$userId/beard.png" );
			$dst_x = $noseCoord [0] - $newBeardSize [0] / 2;
			$dst_y = 0;
			switch ($_POST ["beard-style"]) {
				case 1 :
					$dst_y = $noseCoord [1] - $newBeardSize [1] / 3.75;
					break;
				case 2 :
					$dst_y = $noseCoord [1] - $newBeardSize [1] / 8;
					break;
				case 3 :
					$dst_y = $noseCoord [1] + $newBeardSize [1] / 8;
					break;
				case 4 :
					$dst_y = $noseCoord [1] + $newBeardSize [1] / 8;
					break;
				case 5 :
					$dst_y = $noseCoord [1] - $newBeardSize [1] / 8;
					break;
				case 6 :
					$dst_y = $noseCoord [1] - $newBeardSize [1] / 8;
					break;
				case 7 :
					$dst_y = $noseCoord [1] - $newBeardSize [1] / 8;
					break;
				case 8 :
					$dst_y = $noseCoord [1] - $newBeardSize [1] / 8;
					break;
				case 9 :
					$dst_y = $noseCoord [1] - $newBeardSize [1] / 8;
					break;
				case 10 :
					$dst_y = $noseCoord [1] - $newBeardSize [1] / 8;
					break;
				case 11 :
					$dst_y = $noseCoord [1] - $newBeardSize [1] / 8;
					break;
				case 12 :
					$dst_y = $noseCoord [1] - $newBeardSize [1] / 8;
					break;
			}
			
			$beardImage = new Imagick ( base_url () . "UserUploads/$userId/beard.png" );
			$image->compositeimage ( $beardImage, Imagick::COMPOSITE_OVER, $dst_x, $dst_y );
			
			// $image->writeimage ( "./UserUploads/$userId/xxx.png" );
		}
		
		// Append Nose:
		if (strcmp ( $nosePath, "" ) != 0) {
			$newNoseSize = getimagesize ( "./UserUploads/$userId/nose.png" );
			$dst_x = $noseCoord [0] - $newNoseSize [0] / 2;
			$dst_y = $noseCoord [1] - $newNoseSize [1] / 2;
			
			$noseImage = new Imagick ( base_url () . "UserUploads/$userId/nose.png" );
			$image->compositeimage ( $noseImage, Imagick::COMPOSITE_OVER, $dst_x, $dst_y );
			
			// $image->writeimage ( "./UserUploads/$userId/xxx.png" );
		}
		
		// Append Hair:
		if (strcmp ( $hairPath, "" ) != 0) {
			$newHairSize = getimagesize ( "./UserUploads/$userId/hair.png" );
			switch ($_POST ["hair-style"]) {
				case 1 :
					$dst_x = $eyeCoord [0] - $newHairSize [0] / 4.2;
					$dst_y = $eyeCoord [1] - $newHairSize [1] / 1.1;
					break;
				case 2 :
					$dst_x = $eyeCoord [0] - $newHairSize [0] / 3.6;
					$dst_y = $eyeCoord [1] - $newHairSize [1] / 2.2;
					break;
				case 3 :
					// save new hair image because of size
					$newHairWidth = (strcmp ( $hairPath, "" ) != 0) ? ($hairSize [0] * $proportion) * 2.5 . "x" : 0;
					if (strcmp ( $hairPath, "" ) != 0)
						exec ( "convert ./$hairPath -resize $newHairWidth ./UserUploads/$userId/hair.png" );
					$newHairSize = getimagesize ( "./UserUploads/$userId/hair.png" );
					$dst_x = $eyeCoord [0] - $newHairSize [0] / 2.2;
					$dst_y = $eyeCoord [1] - $newHairSize [1] / 2;
					break;
				case 4 :
					$newHairWidth = (strcmp ( $hairPath, "" ) != 0) ? ($hairSize [0] * $proportion) * 1.2 . "x" : 0;
					if (strcmp ( $hairPath, "" ) != 0)
						exec ( "convert ./$hairPath -resize $newHairWidth ./UserUploads/$userId/hair.png" );
					$newHairSize = getimagesize ( "./UserUploads/$userId/hair.png" );
					$dst_x = $eyeCoord [0] - $newHairSize [0] / 2.5;
					$dst_y = $eyeCoord [1] - $newHairSize [1] / 1.5;
					break;
				case 5 :
					$newHairWidth = (strcmp ( $hairPath, "" ) != 0) ? ($hairSize [0] * $proportion) * 1.5 . "x" : 0;
					if (strcmp ( $hairPath, "" ) != 0)
						exec ( "convert ./$hairPath -resize $newHairWidth ./UserUploads/$userId/hair.png" );
					$newHairSize = getimagesize ( "./UserUploads/$userId/hair.png" );
					$dst_x = $eyeCoord [0] - $newHairSize [0] / 2.3;
					$dst_y = $eyeCoord [1] - $newHairSize [1] / 1.3;
					break;
				case 6 :
					$newHairWidth = (strcmp ( $hairPath, "" ) != 0) ? ($hairSize [0] * $proportion) * 2 . "x" : 0;
					if (strcmp ( $hairPath, "" ) != 0)
						exec ( "convert ./$hairPath -resize $newHairWidth ./UserUploads/$userId/hair.png" );
					$newHairSize = getimagesize ( "./UserUploads/$userId/hair.png" );
					$dst_x = $eyeCoord [0] - $newHairSize [0] / 2.3;
					$dst_y = $eyeCoord [1] - $newHairSize [1] / 1.1;
					break;
				case 7 :
					$newHairWidth = (strcmp ( $hairPath, "" ) != 0) ? ($hairSize [0] * $proportion) * 1.7 . "x" : 0;
					if (strcmp ( $hairPath, "" ) != 0)
						exec ( "convert ./$hairPath -resize $newHairWidth ./UserUploads/$userId/hair.png" );
					$newHairSize = getimagesize ( "./UserUploads/$userId/hair.png" );
					$dst_x = $eyeCoord [0] - $newHairSize [0] / 2.8;
					$dst_y = $eyeCoord [1] - $newHairSize [1] / 2.2;
					break;
				case 8 :
					$newHairWidth = (strcmp ( $hairPath, "" ) != 0) ? ($hairSize [0] * $proportion) * 2.2 . "x" : 0;
					if (strcmp ( $hairPath, "" ) != 0)
						exec ( "convert ./$hairPath -resize $newHairWidth ./UserUploads/$userId/hair.png" );
					$newHairSize = getimagesize ( "./UserUploads/$userId/hair.png" );
					$dst_x = $eyeCoord [0] - $newHairSize [0] / 2.3;
					$dst_y = $eyeCoord [1] - $newHairSize [1] / 1.2;
					break;
				case 9 :
					$newHairWidth = (strcmp ( $hairPath, "" ) != 0) ? ($hairSize [0] * $proportion) * 1.9 . "x" : 0;
					if (strcmp ( $hairPath, "" ) != 0)
						exec ( "convert ./$hairPath -resize $newHairWidth ./UserUploads/$userId/hair.png" );
					$newHairSize = getimagesize ( "./UserUploads/$userId/hair.png" );
					$dst_x = $eyeCoord [0] - $newHairSize [0] / 2.3;
					$dst_y = $eyeCoord [1] - $newHairSize [1] / 1.15;
					break;
				case 10 :
					$newHairWidth = (strcmp ( $hairPath, "" ) != 0) ? ($hairSize [0] * $proportion) * 2.2 . "x" : 0;
					if (strcmp ( $hairPath, "" ) != 0)
						exec ( "convert ./$hairPath -resize $newHairWidth ./UserUploads/$userId/hair.png" );
					$newHairSize = getimagesize ( "./UserUploads/$userId/hair.png" );
					$dst_x = $eyeCoord [0] - $newHairSize [0] / 2.3;
					$dst_y = $eyeCoord [1] - $newHairSize [1] / 1.15;
					break;
				case 11 :
					$newHairWidth = (strcmp ( $hairPath, "" ) != 0) ? ($hairSize [0] * $proportion) * 2 . "x" : 0;
					if (strcmp ( $hairPath, "" ) != 0)
						exec ( "convert ./$hairPath -resize $newHairWidth ./UserUploads/$userId/hair.png" );
					$newHairSize = getimagesize ( "./UserUploads/$userId/hair.png" );
					$dst_x = $eyeCoord [0] - $newHairSize [0] / 2.5;
					$dst_y = $eyeCoord [1] - $newHairSize [1] / 1.15;
					break;
			}
			$hairImage = new Imagick ( base_url () . "UserUploads/$userId/hair.png" );
			$image->compositeimage ( $hairImage, Imagick::COMPOSITE_OVER, $dst_x, $dst_y );
		}
		$outputName = "funnyeffect-" . $imageName;
		$result = "./UserUploads/" . $userId . "/" .$outputName;
		$image->rotateimage ( new ImagickPixel ( "#4BA3E6" ), - $rotateAngle );
		$image->writeimage ( $result );
		$outputNameOnly = preg_replace("/\.\w+/", "", $outputName);
		$cloudUpload = \Cloudinary\Uploader::upload("./UserUploads/$userId/$outputName", array("public_id" => "UserUploads/$userId/$outputNameOnly"));
		// Fill transparent background
		$_SESSION["funnyEffectPath"] = $cloudUpload["url"];
		$_SESSION ["isFunnyEffect"] = $imageName;
		
	}
	public function makeIn20Years() {
		$userId = $_SESSION ["userId"];
		$imageName = $_SESSION ["imageName"];
		
		$userImagePath = base_url () . "UserUploads/" . $userId . "/" . $imageName;
		// ---------------------------------------------------------------------------------------------------------
		// $userImage = new Imagick($userImagePath);
		
		// // Test face crop
		// $detector = new FaceDetector('./library/FaceDetector/detection.dat');
		// $detector->faceDetect("./UserUploads/".$userId ."/" . $imageName);
		// $detector->toJpeg("./UserUploads/".$userId . "/". $imageName);
		
		// exec("./bashscript/lucisarteffect -g 1 -s 80 ./UserUploads/$userId/$imageName ./UserUploads/$userId/$imageName", $output, $return);
		// exec("./bashscript/draganeffect -b 1 -c 0 -d 1 -s 100 ./UserUploads/$userId/$imageName ./UserUploads/$userId/$imageName", $output, $return);
		
		// ---------------------------------------------------------------------------------------------------------
		echo "Before analyzing:<br><br><img src=$userImagePath></img><br><br>";
		
		$dir = $userImagePath;
		
		global $rekognition;
		$resize_factor = 1;
		$parsed_obj = $rekognition->RkFaceDetect ( $dir, $resize_factor, Rekognition_API::REQUEST_DIR, Rekognition_API::RETURN_PARSED );
		
		global $orbgui;
		$orbgui->SetImage ( $dir );
		$orbgui->DrawObjects ( $parsed_obj->GetFaces (), $resize_factor );
		
		$base64_str = base64_encode ( $orbgui->GetImage () );
		echo "After analyzing:<br><br><img src='data:image/jpeg;base64," . $base64_str . "' /><br><br>";
		
		$resultArray = ( array ) $parsed_obj;
		
		$returnFaceAttr;
		// counter for Rekognition_Parserfaces_
		$i = 0;
		foreach ( $resultArray as $key => $value ) {
			$tmp = $key;
			if ($i == 2) {
				$returnFaceAttr = ( array ) $resultArray [$key] [0];
				break;
			}
			// strlen vs mb_strlen;
			// http://wpengineer.com/2410/dont-use-strlen/
			$i ++;
		}
		
		$j = 0;
		$faceBound = array ();
		$leftEye = array ();
		$rightEye = array ();
		$nose = array ();
		$leftMounth = array ();
		$rightMounth = array ();
		
		foreach ( $returnFaceAttr as $key => $value ) {
			if ($j == 1) {
				$faceBound = ( array ) $returnFaceAttr [$key];
			} else if ($j == 3) {
				$features = $returnFaceAttr [$key];
				$x = 0;
				foreach ( $features as $key__ => $value__ ) {
					if ($x == 0) {
						$leftEye = ( array ) $features [$key__];
					} else if ($x == 1) {
						$rightEye = ( array ) $features [$key__];
					} else if ($x == 2) {
						$nose = ( array ) $features [$key__];
					} else if ($x == 3) {
						$leftMounth = ( array ) $features [$key__];
					} else if ($x == 5) {
						$rightMounth = ( array ) $features [$key__];
						break;
					}
					$x ++;
				}
				break;
			}
			$j ++;
		}
		
		// Make face
		$boundLeftX = 0;
		$boundLeftY = 0;
		$boundBoxWidth = 0;
		$boundBoxHeight = 0;
		$i = 0;
		foreach ( $faceBound as $key => $value ) {
			if ($i == 0) {
				$boundLeft = ( array ) $faceBound [$key];
				$j = 0;
				foreach ( $boundLeft as $keyJ => $valueJ ) {
					if ($j == 0)
						$boundLeftX = $boundLeft [$keyJ];
					else
						$boundLeftY = $boundLeft [$keyJ];
					$j ++;
				}
			} else if ($i == 1) {
				$boundBox = ( array ) $faceBound [$key];
				$j = 0;
				foreach ( $boundBox as $keyJ => $valueJ ) {
					if ($j == 0)
						$boundBoxWidth = $boundBox [$keyJ];
					else
						$boundBoxHeight = $boundBox [$keyJ];
					$j ++;
				}
			}
			
			$i ++;
		}
		$faceCoord = array (
				$boundLeftX,
				$boundLeftY,
				$boundBoxWidth + 20,
				$boundBoxHeight + 20 
		);
		// Make Eye
		$leftEyeX = 0;
		$leftEyeY = 0;
		$rightEyeX = 0;
		$rightEyeY = 0;
		$i = 0;
		foreach ( $leftEye as $key => $value ) {
			if ($i == 0)
				$leftEyeX = $leftEye [$key];
			else
				$leftEyeY = $leftEye [$key];
			$i ++;
		}
		$i = 0;
		foreach ( $rightEye as $key => $value ) {
			if ($i == 0)
				$rightEyeX = $rightEye [$key];
			else
				$rightEyeY = $rightEye [$key];
			$i ++;
		}
		$eyeCoord = array (
				$leftEyeX,
				$leftEyeY,
				$rightEyeX,
				$rightEyeY 
		);
		
		// Make Nose
		$noseX = 0;
		$noseY = 0;
		$i = 0;
		foreach ( $nose as $key => $value ) {
			if ($i == 0)
				$noseX = $nose [$key];
			else
				$noseY = $nose [$key];
			$i ++;
		}
		
		$noseCoord = array (
				$noseX,
				$noseY 
		);
		// Make Mounth
		$leftMounthX = 0;
		$leftMounthY = 0;
		$i = 0;
		foreach ( $leftMounth as $key => $value ) {
			if ($i == 0)
				$leftMounthX = $leftMounth [$key];
			else
				$leftMounthY = $leftMounth [$key];
			$i ++;
		}
		$rightMounthX = 0;
		$rightMounthY = 0;
		$i = 0;
		foreach ( $rightMounth as $key => $value ) {
			if ($i == 0)
				$rightMounthX = $rightMounth [$key];
			else
				$rightMounthY = $rightMounth [$key];
			$i ++;
		}
		$mounthCoord = array (
				$leftMounthX,
				$leftMounthY,
				$rightMounthX,
				$rightMounthY 
		);
		
		// Rotate angle
		$twoEyesVector = array (
				$eyeCoord [2] - $eyeCoord [0],
				$eyeCoord [3] - $eyeCoord [1] 
		);
		$xUnitVector = array (
				1,
				0 
		);
		$rotateAngle = 180 / pi () * acos ( ($twoEyesVector [0]) / sqrt ( $twoEyesVector [0] * $twoEyesVector [0] + $twoEyesVector [1] * $twoEyesVector [1] ) );
		$rotateAngle = ($eyeCoord [3] >= $eyeCoord [1]) ? $rotateAngle : - $rotateAngle;
		
		$standardWidth = 3 * sqrt ( $twoEyesVector [0] * $twoEyesVector [0] + $twoEyesVector [1] * $twoEyesVector [1] ) / 2;
		
		$twoEyesMidPoints = array (
				$eyeCoord [2] / 2 + $eyeCoord [0] / 2,
				$eyeCoord [3] / 2 + $eyeCoord [1] / 2 
		);
		$eyeWrinkleToEyesLine = sqrt ( ($eyeCoord [1] - $twoEyesMidPoints [1]) * ($eyeCoord [1] - $twoEyesMidPoints [1]) - ($eyeCoord [1] - $twoEyesMidPoints [1]) * ($eyeCoord [1] - $twoEyesMidPoints [1]) ) / 4;
		echo "</br>" . $rotateAngle . "</br>";
		var_dump ( $faceCoord );
		echo "</br>";
		var_dump ( $eyeCoord );
		echo "</br>";
		var_dump ( $noseCoord );
		echo "</br>";
		var_dump ( $mounthCoord );
		$halfFaceWidth = $faceCoord [0] / 2;
		// Darken all Face
		$command = "convert -region $faceCoord[2]x$faceCoord[3]+$faceCoord[0]+$faceCoord[1] -level 20%,100%,0.5 ./UserUploads/$userId/$imageName ./UserUploads/$userId/$imageName ";
		exec ( $command );
		$command = "convert  -level 0%,100%,2 ./UserUploads/$userId/$imageName ./UserUploads/$userId/$imageName ";
		exec ( $command );
		// Rotate Image with angle = -$rotateAngle;
		$command = "convert  -rotate -$rotateAngle ./UserUploads/$userId/$imageName ./UserUploads/$userId/$imageName ";
		exec ( $command );
		// Draw EyeWrinkles
		$leftWrinkleMidPoints = array (
				$eyeCoord [0],
				$eyeCoord [1] + $eyeWrinkleToEyesLine 
		);
		$rightWrinkleMidPoints = array (
				$eyeCoord [2],
				$eyeCoord [3] + $eyeWrinkleToEyesLine 
		);
		// Left Wrinkle
		$firstLeftWrinkle = array (
				$leftWrinkleMidPoints [0] - $standardWidth / 2,
				$leftWrinkleMidPoints [1] 
		);
		$secondLeftWrinkle = array (
				$leftWrinkleMidPoints [0] + $standardWidth / 2,
				$leftWrinkleMidPoints [1] 
		);
		// Right Wrinkle
		$firstRightWrinkle = array (
				$rightWrinkleMidPoints [0] - $standardWidth / 2,
				$rightWrinkleMidPoints [1] 
		);
		$secondRightWrinkle = array (
				$rightWrinkleMidPoints [0] + $standardWidth / 2,
				$rightWrinkleMidPoints [1] 
		);
		$lineCoord = "$firstLeftWrinkle[0],$firstLeftWrinkle[1] $secondLeftWrinkle[0],$secondLeftWrinkle[1]";
		
		$command = "convert -fill \"rgb(65, 59, 59)\" none -draw \"line  $lineCoord\" ./UserUploads/$userId/$imageName ./UserUploads/$userId/$imageName";
		echo "</br>" . "$command" . "</br>";
		exec ( $command );
		
		$lineCoord = "$firstRightWrinkle[0],$firstRightWrinkle[1] $secondRightWrinkle[0],$secondRightWrinkle[1]";
		$command = "convert -fill \"rgb(65, 59, 59)\" none -draw \"line  $lineCoord\" ./UserUploads/$userId/$imageName ./UserUploads/$userId/$imageName";
		echo "</br>" . "$command" . "</br>";
		exec ( $command );
		//
		
		// Rotate to the original
		$command = "convert  -rotate $rotateAngle ./UserUploads/$userId/$imageName ./UserUploads/$userId/$imageName ";
		exec ( $command );
		echo "<br><br>Last Result:<br><br><img src=$userImagePath></img><br><br>";
	}
	
	public function sketch(){
		$userId = $_SESSION ["userId"];
		$imageName = $_SESSION ["imageName"];
		
		if(!isset($_SESSION["imagePath"]))
			$userImagePath = base_url () . "UserUploads/" . $userId . "/" . $imageName;
		else 
			$userImagePath = $_SESSION["imagePath"];
		$outputName = "sketch-" . $imageName;
		exec ( "./bashscript/sketch -k desat -c 125 -g $userImagePath  ./UserUploads/$userId/$outputName" );
		$outputNameOnly = preg_replace("/\.\w+/", "", $outputName);
		
		$cloudUpload = \Cloudinary\Uploader::upload("./UserUploads/$userId/$outputName", array("public_id" => "UserUploads/$userId/$outputNameOnly"));
		//delete in server
		$_SESSION["sketchPath"] = $cloudUpload["url"];
		unlink("./UserUploads/$userId/$outputName");
	}
}